package org.sfx.util

import java.lang.reflect.Type
import org.sfx.rich.Enrich._

trait Accessor {
  def name: String
  def accessorType: Type
  def subject: Object
}

trait Getter extends Accessor
trait Setter extends Accessor

trait StringGetter extends Getter {
  def stringValue: String
}

trait StringSetter extends StringGetter with Setter {
  def stringValue_=(value: String): Unit
}

trait ObjectGetter extends Getter {
  def objectValue: Object
}

trait ObjectSetter extends ObjectGetter with Setter {
  def objectValue_=(value: Object): Unit
}

trait BooleanGetter extends Getter {
  def booleanValue: Boolean
}

trait BooleanSetter extends BooleanGetter with Setter {
  def booleanValue_=(value: Boolean): Unit
}

trait BooleanAsStringGetter extends StringGetter with BooleanGetter {
  override def stringValue: String = booleanValue.toString()
}

trait BooleanAsStringSetter extends StringSetter with BooleanSetter {
  override def stringValue_=(value: String): Unit = {
    booleanValue = java.lang.Boolean.parseBoolean(value)
  }
}

trait IntGetter extends Getter {
  def intValue: Int
}

trait IntSetter extends IntGetter with Setter {
  def intValue_=(value: Int): Unit
}

trait IntAsStringGetter extends StringGetter with IntGetter {
  override def stringValue: String = intValue.toString()
}

trait IntAsStringSetter extends StringSetter with IntSetter {
  override def stringValue_=(value: String): Unit = {
    intValue = java.lang.Integer.parseInt(value)
  }
}

trait DoubleGetter extends Getter {
  def doubleValue: Double
}

trait DoubleSetter extends DoubleGetter with Setter {
  def doubleValue_=(value: Double): Unit
}

trait DoubleAsStringGetter extends StringGetter with DoubleGetter {
  override def stringValue: String = doubleValue.toString()
}

trait DoubleAsStringSetter extends StringSetter with DoubleSetter {
  override def stringValue_=(value: String): Unit = {
    doubleValue = java.lang.Double.parseDouble(value)
  }
}

case class InterpretedAccessor(name: String, accessorType: Type, subject: Object) extends Accessor {
  def bind(): Unit = {
    //Interpreter.bind(name, subject)(TypeWrangler.javaType(accessorType).asInstanceOf[Manifest[Object]])
  }
  
  def evalAndSet(expression: String): Unit = {
    bind()
    Interpreter.interpret(name + ".set(" + expression.inspect + ")")
  }
}
